package com.dream.api.controller;

import java.util.Enumeration;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.dream.app.service.UserService;
import com.dream.base.controller.BaseController;
import com.dream.model.app.AppUser;
import com.dream.utils.annotation.AccessLog;
import com.dream.utils.annotation.SkipAuthority;
import com.dream.utils.cookie.CookieUtils;
import com.dream.utils.log.DreamLogUtils;
import com.dream.utils.random.validate.RandomValidateCodeUtils;
import com.dream.utils.system.cfg.SystemConfigUtils;
import com.dream.vo.api.ApiResult;
import com.dream.vo.api.StatusCode;
import com.dream.vo.app.UserVO;
import com.dream.vo.base.Constants;
import com.dream.vo.base.FirstGroup;
import com.google.common.collect.Maps;
import com.google.gson.Gson;

/**
 * @copyright evan
 * @author evan
 * @Revision
 * @date 2013/9/29
 */
@Controller
@RequestMapping(value = "/api")
public class LoginController extends BaseController{
	
	@Autowired
	private UserService userService;
	
	
	@ResponseBody
	@RequestMapping(value = "/login",produces = "text/json;charset=UTF-8")
	@AccessLog(module="api",content="用户登录")
	@SkipAuthority
	public String login(Model modelMap,@Validated({FirstGroup.class}) UserVO userVO,BindingResult valResult,HttpServletResponse response) {
		
		ApiResult result = new ApiResult();

		if(valResult.hasErrors()){
			result.setResult(false);
			result.setMessage(this.messageSource.getMessage("err0001", null, this.getLocale()));
			
		}else{
			int lockCount = SystemConfigUtils.instance().getInteger("login.lock.count", 6);
			int unlockMins = SystemConfigUtils.instance().getInteger("login.unlock.minitue", 10);
			boolean lockFalg = SystemConfigUtils.instance().getBoolean("login.lock.flag");
			try{
				 
				 Boolean isLocked = false;
				 if(lockFalg){
					 isLocked = userService.isLockedUser(userVO, lockCount, unlockMins);
				 }
				 
				 if(isLocked == null){
					 result.setResult(false);
					 result.setMessage(this.messageSource.getMessage("err0009", null, this.getLocale()));
				 }else if(isLocked){
					 result.setResult(false);
					 result.setMessage("err0021");
				 }else{
						AppUser user = userService.login(userVO);
						//email or password is wrong
						if(user==null ){
							 result.setResult(false);
							 result.setMessage(this.messageSource.getMessage("err0009", null, this.getLocale()));
						}else{
							//pass the validation
							result.setResult(true);
							result.setMessage(new Gson().toJson(user.toApiUser()));
							saveUser(user,userVO.getRememberMe(),getRequest(),response);
						}
				 }
			}catch(Exception ex){
				result.setResult(false);
				response.setStatus(StatusCode.EX_SYS);
				DreamLogUtils.error(this,"login","login occured exception", ex);
			}
		}
		return new Gson().toJson(result);
	}
	
	@ResponseBody
	@RequestMapping(value = "/logout")
	@AccessLog(module="api",content="用户注销")
	@SkipAuthority
	public void logout(HttpServletResponse response) {
		
		HttpSession session = getRequest().getSession(true);
		try{
			 session = getRequest().getSession(true);
			if (session != null){
				ACTIVE_SESSION.remove(session.getId());
				session.removeAttribute(Constants.USER_ID);
				session.invalidate();
				
			}
		}catch(Exception e){
			DreamLogUtils.error(this, "logout", "logout exception", e);
		}
		
	}
	
	/**
	 * 
	 * @copyright evan
	 * @author evan
	 * @date 2013-9-3
	 * @param user
	 * @param rememberMe
	 * @param request
	 * @param response
	 */
	private void saveUser(AppUser user,String rememberMe,HttpServletRequest request,HttpServletResponse response){
		
		//session fixable
		HttpSession session = request.getSession();
		Map<String,Object> map = Maps.newHashMap();
		
		if(session == null){
			return ;
		}
		for(Enumeration<?> enumer = session.getAttributeNames();enumer.hasMoreElements();){
			String key = (String)enumer.nextElement();
			map.put(key, session.getAttribute(key));
		}
		session.invalidate();
		map.remove(RandomValidateCodeUtils.RANDOM_IMAGE_VALIDATE);
		session = request.getSession(true);
		for(Map.Entry<String, Object> entry : map.entrySet()){
			session.setAttribute(entry.getKey(), entry.getValue());
		}
		session.setAttribute(Constants.USER_ID, user);
		ACTIVE_SESSION.put(session.getId(), session);
		
		//save user id to cookie
		if("on".equals(rememberMe)){
			CookieUtils.addCookie(response, request, Constants.USER_ID, user.getId());
		}else{
			CookieUtils.removeCookie(response, request, Constants.USER_ID);
		}
	}
	
	
}
